/*
 * Implementation of QUsersDialog.
 *
 * Shows a dialog allowing user account control.
 */

#include <QtGui>
#include "qusersdialog.h"

#include <algorithm>

// default constructor
QUsersDialog::QUsersDialog (QWidget* parent) : QDialog(parent) {
	QHBoxLayout *layout = new QHBoxLayout();
	setWindowTitle("Users");
	layout->addWidget(&userList);

	QPushButton *addButton = new QPushButton("&Add user...");
	QPushButton *delButton = new QPushButton("&Remove user");
	QPushButton *loginButton = new QPushButton("&Log in");

	QVBoxLayout *buttonLayout = new QVBoxLayout();

	buttonLayout->addWidget(addButton);
	buttonLayout->addWidget(delButton);
	buttonLayout->addStretch();
	buttonLayout->addWidget(loginButton);
	layout->addLayout(buttonLayout);

	setLayout(layout);

	// connect up the button signals
	connect (addButton, SIGNAL(clicked()), this, SLOT(addUser()));
        connect (delButton, SIGNAL(clicked()), this, SLOT(removeUser()));
        connect (loginButton, SIGNAL(clicked()), this, SLOT(login()));
        connect(&userList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(login(QModelIndex)));
        //connect (loginButton, SIGNAL(clicked()), this, SLOT(close()));
}

// associate this dialog with a UserCollection object
void QUsersDialog::setUserCollection(UserCollection* uc) {
	userCollection = uc;
	populate();
}

// populate the list widget with usernames
void QUsersDialog::populate () {
        foreach (User user, *userCollection) {
                userList.addItem(user.getName());
	}
}

void QUsersDialog::addUser () {
	QDialog newUserDialog(this);
	newUserDialog.setWindowTitle("Add new user");
	QHBoxLayout layout;
	QLineEdit edit;
	QPushButton done("&Create");
	QLabel label("User name:");
        // more potent than setDefault
        done.setAutoDefault(true); // make default button
	layout.addWidget(&label);
	layout.addWidget(&edit);
	layout.addWidget(&done);
	newUserDialog.setLayout(&layout);

        // bind 'create' button to close dialog
        connect(&done, SIGNAL(clicked()), &newUserDialog, SLOT(accept()));

	// show modal dialog
	newUserDialog.exec();

	// create a new user
	// NOTE THAT THIS MEMORY HAS TO BE FREED.
	// it should be fine to free it along with the
	// users read in from XML.
	// i.e. it should be fine to delete all pointers
	// in UserCollection destructor
	User* newUser = new User(edit.text());
        userCollection->append(*newUser);
        delete newUser;

	// refresh the 'users' list
        refreshUserCollection();
}


// Remove user from list and from user collection.
void QUsersDialog::removeUser () {
    // extract user name data item from list
    if (userList.selectedItems().empty())
        return;
    QString username = userList.selectedItems().at(0)->data(Qt::DisplayRole).toString();
    // find the corresponding user in the user collection. seq. search

    UserCollection::iterator r = std::find(userCollection->begin(), userCollection->end(), username);
    // remove it
    userCollection->erase(r);

    refreshUserCollection();
}

// update the user list and send a signal that the user collection changed
void QUsersDialog::refreshUserCollection() {
    // refresh
    userList.clear();
    populate();
    emit userCollectionChanged();
}

// User pressed login button
void QUsersDialog::login () {
    if (userList.selectedItems().empty())
        return;

    QString username = userList.selectedItems().at(0)->data(Qt::DisplayRole).toString();
    close();
    emit signIn(username);
}

// wrapper for listWidget::doubleClicked() slot interface
void QUsersDialog::login(QModelIndex index) {
    login();
}

// save to test xml file for debugging purposes.
// used because need QObject for triggered save.
// parent window will implement this functionality, but
// sandbox is standalone and can't make a regular free static function a slot
void QUsersDialog::saveTest() {
    userCollection->save("test_output.xml");
}
